package com.nuoniu.sibanyun.service.erp.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.nuoniu.sibanyun.common.constant.RedisConstant;
import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.common.lang.DateUtils;
import com.nuoniu.sibanyun.entity.SysCompany;
import com.nuoniu.sibanyun.entity.dto.ErpAccountEditDto;
import com.nuoniu.sibanyun.entity.erp.ErpAccount;
import com.nuoniu.sibanyun.entity.erp.ErpPeriod;
import com.nuoniu.sibanyun.entity.vo.ErpAccountVo;
import com.nuoniu.sibanyun.mapper.erp.ErpAccountMapper;
import com.nuoniu.sibanyun.service.erp.*;
import com.nuoniu.sibanyun.service.redis.RedisService;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 账套信息 服务实现类
 * </p>
 *
 * @author baiqiang
 * @since 2020-09-22
 */
@Service
public class ErpAccountServiceImpl extends ServiceImpl<ErpAccountMapper, ErpAccount> implements IErpAccountService {

    @Autowired
    private IErpPeriodService erpPeriodService;
    @Autowired
    @Lazy
    private ErpInitAccountDataService erpInitAccountDataService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private ErpInitAccountDataService accountDataService;

    @Override
    public Integer getCurrentAccountId() {
        UserInfo userInfo = UserThreadLocal.get();
        if(userInfo.getCompanyId().equals(1)) {
            return 0;
        }

        Object accountIdObj = redisService.get(RedisConstant.ACCOUNT_REDIS_KEY + userInfo.getCompanyId());
        if(null != accountIdObj) {
            Integer accountId = (Integer)accountIdObj;
            return accountId;
        }else {
            Integer currentAccountId = baseMapper.getCurrentAccountId(userInfo.getCompanyId());
//            if(currentAccountId == null) {
//                throw  new NuoNiuException(5001,"请创建账套");
//            }
//
            redisService.set(RedisConstant.ACCOUNT_REDIS_KEY  + userInfo.getCompanyId(),currentAccountId);
            return currentAccountId;
        }
    }

    @Override
    public List<ErpAccountVo> listErpAccount() {
        UserInfo userInfo = UserThreadLocal.get();
        List<ErpAccountVo> erpAccountVoList = baseMapper.listErpAccountVo(userInfo.getCompanyId());
        List<ErpPeriod> erpPeriods = erpPeriodService.listCurrentCompanyErpPeriod();
        erpAccountVoList.forEach(f->{
            List<ErpPeriod> erpPeriodList = erpPeriods.stream().filter(p -> p.getAccountId().toString().equals(f.getId().toString())).collect(Collectors.toList());
            f.setErpPeriodList(erpPeriodList);
        });
        return erpAccountVoList;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void addErpAccount(ErpAccount erpAccount) {
        String currentYearStr = DateUtils.getYear();
        Integer currentYear = Integer.valueOf(currentYearStr);
        UserInfo userInfo = UserThreadLocal.get();
        ErpAccount lastErpAccount = getLastErpAccount();
        if(null != lastErpAccount ){
            if(lastErpAccount.getStatus() < 2){
                throw new NuoNiuException("上一年账套还未结算，不能创建下一年账套");
            }else{
                int nextYear = lastErpAccount.getAccountYear() + 1;
                erpAccount.setAccountYear(nextYear);
                erpAccount.setBeginDate(LocalDate.of(nextYear,1,1));
                erpAccount.setEndDate(LocalDate.of(nextYear,12,31));
                erpAccount.setEnableDuration(1);
                erpAccount.setIsFirstYear(false);
            }
        }else{
            erpAccount.setAccountYear(currentYear);
            erpAccount.setIsFirstYear(true);
        }

        erpAccount.setAccountName(userInfo.getCompanyName());
        erpAccount.setCompanyId(userInfo.getCompanyId());
        boolean save = save(erpAccount);
        if(save && null == lastErpAccount){
            int id = erpAccount.getId().intValue();
            erpInitAccountDataService.init(userInfo,id);
        }
    }

    @Override
    public void editErpAccount(ErpAccountEditDto erpAccountEditDto) {
        UserInfo userInfo = UserThreadLocal.get();
        Long accountId = erpAccountEditDto.getId();
        if(null == accountId)throw new NuoNiuException("ID不能为空");
        ErpAccount oldOne = getById(accountId);
        if(null == oldOne)throw new NuoNiuException("当前账套不存在");
        if(!oldOne.getCompanyId().equals(userInfo.getCompanyId()))throw new NuoNiuException("你无权修改当前账套，公司信息错误");
        ErpAccount erpAccount = new ErpAccount();
        BeanUtils.copyProperties(erpAccountEditDto,erpAccount);

        if(oldOne.getStatus() > 1){
            throw new NuoNiuException("当前账套已经结算，不能修改");
        }
        updateById(erpAccount);
    }

    @Override
    public ErpAccount getLastErpAccount() {
        UserInfo userInfo = UserThreadLocal.get();
        QueryWrapper<ErpAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("company_id",userInfo.getCompanyId());
        queryWrapper.orderByDesc("account_year");
        queryWrapper.last("limit 1");
        ErpAccount one = getOne(queryWrapper, false);
        return one;
    }

    @Override
    public void updateAccountName(SysCompany company) {
        ErpAccount lastErpAccount = getLastErpAccount();
        UpdateWrapper<ErpAccount> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",lastErpAccount.getId());
        updateWrapper.set("account_name",company.getCompanyName());
        update(updateWrapper);
    }

    public  ErpPeriod getPeriod(LocalDate voucherDate) {
        return erpPeriodService.getByDate(voucherDate, UserThreadLocal.get().getCompanyId(), getCurrentAccountId());
    }

    @Override
    public void initErpAccount(Long companyId, String companyName) {
        Integer year = Integer.valueOf(DateUtils.getYear());
        ErpAccount account = new ErpAccount();
        account.setCompanyId(companyId.intValue());
        account.setAccountName(companyName);
        account.setAccountYear(year);
        account.setIsFirstYear(true);
        account.setBeginDate(LocalDate.parse(year + "-01-01"));
        account.setEndDate(LocalDate.parse(year + "-12-31"));
        account.setEnableDuration(1);
        account.setBaseCurrencyName("人民币");
        account.setBaseCurrencySymbol("￥");
        account.setBaseCurrencyCode("RMB");
        this.save(account);

        //初始化期间
        List<ErpPeriod> periodList = new ArrayList<>();
        LocalDate date = LocalDate.of(year, 12, 01);
        for(int i=12; i>0; i--) {
            LocalDate lastMonth = date.minusMonths(12 - i); // 当前月份减1
            LocalDate firstDay = lastMonth.with(TemporalAdjusters.firstDayOfMonth()); // 获取当前月的第一天
            LocalDate lastDay = lastMonth.with(TemporalAdjusters.lastDayOfMonth()); // 获取当前月的最后一天
            ErpPeriod period = new ErpPeriod();
            period.setAccountId(account.getId().intValue());
            period.setCompanyId(companyId.intValue());
            period.setBeginDate(firstDay);
            period.setEndDate(lastDay);
            period.setCurrentYear(year);
            period.setCurrentPeriod(i);
            periodList.add(period);
        }
        erpPeriodService.saveBatch(periodList);

        //初始化其他
        UserInfo userInfo = new UserInfo();
        userInfo.setCompanyId(companyId.intValue());
        accountDataService.init(userInfo, account.getId().intValue());
    }
}
